from channels.exceptions import StopConsumer
from channels.generic.websocket import WebsocketConsumer

from apps.fun import user_online, msg_send
from apps.token import _check_token
from h5.models import ChatUser


class ChatConsumer(WebsocketConsumer):
    group_id = None

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)


    def websocket_connect(self, message):
        """
        客户端向服务端发送websocket连接的请求时自动触发。
        验证逻辑:
        链接时传递参数:user_id--用户ID
        token:--链接token
        示例:B3#e0e22598fb93#N7  从第3位到第10位的用户ID+密钥md5加密字段
        定义密钥位5gzhike
        """
        self.user_id = self.scope["url_route"]["kwargs"].get("user_id")
        token = self.scope["url_route"]["kwargs"].get("token")
        self.accept()
        # 在这里可以验证token
        if not _check_token(self.user_id, token):
            self.send(text_data='token验证失败')
            self.close()
            return
        # 用户上线 验证用户是否是本系统内用户
        if not ChatUser.objects.filter(id=self.user_id).exists():
            self.send(text_data='该用户不在本系统')
            self.close()
            return
        user_online(self.user_id,self.channel_name)

    def websocket_receive(self, message):
        """
        客户端基于websocket向服务端发送数据时，自动触发接收消息。
        message字段类型 {'type': 'websocket.receive', 'text': '33'}
        """
        # print(f"2 > 服务端接收客户端的消息, message is {message}")
        recv_data = message["text"]
        if recv_data == "exit":     # 服务端主动关闭websocket连接时，前端会执行对应的 onclose
            self.close()
            user_online(self.user_id, status=0)
            # raise StopConsumer()    # raise主动抛异常后，websocket_disconnect 就不在执行了，多用于`只处理服务端向客户端断开`的场景
            return
        res = msg_send(message,c_name=self.channel_name)
        if res == 0:
            self.send(text_data='对方不在线')

    def send_msg(self, msg):
        self.send(text_data=msg['message'])

    def websocket_disconnect(self, message):
        """
        客户端与服务端断开websocket连接时自动触发(不管是客户端向服务端断开还是服务端向客户端断开都会执行)
        """
        print("客户端和服务端断开连接:"+self.user_id)
        user_online(self.user_id, status=0)
        self.close()
        raise StopConsumer()